// 搞茅台那么就爬取一下茅台的净利润（扣除非经常损益），并保存为 excel 文件。

const fs = require('fs');
const xlsx = require('node-xlsx');
const cheerio = require('cheerio');
const axios = require('axios');

const requestHeaders = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',
    'Referer': 'http://quotes.money.163.com/f10/zycwzb_600519'
};

class Crawler {
    constructor(options) {
        this.pageUrl = options.pageUrl;
        this.cachePath = options.cachePath || './cache.html';
        this.exportExcelPath = options.exportExcelPath || 'excel.xlsx';
    }

    async start () {
        let html = await this.readLocalCache();
        if (!html) {
            html = await this.request();
        }
        const parseResult = this.processPageHTML(html);
        this.buildXlsx(parseResult);
    }

    checkFileExist (filePath) {
        try {
            fs.statSync(filePath);
            return true;
        } catch (err) {
            fs.writeFileSync(filePath, '', 'utf-8');
            return false;
        }
    }

    createLocalCache (html = '') {
        this.checkFileExist(this.cachePath);
        return fs.writeFileSync(this.cachePath, html, 'utf-8');
    }

    async readLocalCache () {
        this.checkFileExist(this.cachePath);
        return fs.readFileSync(this.cachePath, 'utf-8');
    }

    async request () {
        return axios.get(this.pageUrl, {
            headers: requestHeaders
        }).then(result => {
            this.createLocalCache(result.data);
            return Promise.resolve(result.data);
        }).catch(err => {
            console.log('请求出错');
            console.log(err);
            return Promise.reject(err);
        });
    }

    processPageHTML (html) {
        const result = { title: [], profitRateList: [] };
        const $ = cheerio.load(html);
        const $reportTable = $('.table_bg001.border_box.limit_sale.scr_table');

        const tableTitle = $reportTable.find('tbody tr:first-child');
        const tableTitleTds = tableTitle.children();

        const profitRateTr = $reportTable.find('tbody tr:nth-child(12)');
        const profitRateTds = profitRateTr.children();

        for (let i = 0; i < tableTitleTds.length; i++) {
            const titleTd = tableTitleTds[i];
            result.title.push($(titleTd).text().trim());
            const profitRateTd = profitRateTds[i];
            result.profitRateList.push($(profitRateTd).text().trim());
        }

        return result;
    }

    buildXlsx (dataObj) {
        const values = Object.values(dataObj);
        const excelBuffer = xlsx.build([{ name: '茅台', data: values }]);
        fs.writeFileSync(this.exportExcelPath, excelBuffer, 'buffer');
        console.log('导出 excel 成功');
    }

}

const crawler = new Crawler({ pageUrl: 'http://quotes.money.163.com/f10/zycwzb_600519.html#01c01' });
crawler.start();
